package io.github.uicdb.et.item.weapon;

import io.github.uicdb.et.ModEffects;
import io.github.uicdb.et.ModHelper;
import io.github.uicdb.et.ModElements;
import mod.azure.azurelib.common.api.client.renderer.GeoItemRenderer;
import mod.azure.azurelib.common.api.common.animatable.GeoItem;
import mod.azure.azurelib.common.internal.client.RenderProvider;
import mod.azure.azurelib.common.internal.common.util.AzureLibUtil;
import mod.azure.azurelib.core.animatable.instance.AnimatableInstanceCache;
import mod.azure.azurelib.core.animation.AnimatableManager;
import mod.azure.azurelib.core.animation.Animation;
import mod.azure.azurelib.core.animation.AnimationController;
import mod.azure.azurelib.core.animation.RawAnimation;
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.UseAnim;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.NotNull;

import java.util.function.Consumer;

public class WaterStaffItem extends StaffItem implements GeoItem {

    private final AnimatableInstanceCache cache = AzureLibUtil.createInstanceCache(this);

    @Override
    public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
        controllers.add(
                new AnimationController<>(this, "using", event -> event.setAndContinue(RawAnimation.begin().then("using", Animation.LoopType.LOOP)))
        );
    }

    @Override
    public AnimatableInstanceCache getAnimatableInstanceCache() {
        return cache;
    }


    @Override
    public void createRenderer(Consumer<RenderProvider> consumer) {
        consumer.accept(new RenderProvider() {
            GeoItemRenderer<WaterStaffItem> renderer = null;

            @Override
            public BlockEntityWithoutLevelRenderer getCustomRenderer() {
                if (renderer == null) renderer = new WaterStaffRenderer();
                return renderer;
            }
        });
    }

    public WaterStaffItem(Properties properties) {
        super(properties, ModElements.WATER.getElemental().getElementHolder(), 5, 30, 150);
    }

    @Override
    public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand usedHand) {
        // if (level instanceof ServerLevel serverLevel)
        // triggerAnim(player, GeoItem.getOrAssignId(player.getItemInHand(usedHand), serverLevel), "using", "using");
        return super.use(level, player, usedHand);
    }

    @Override
    public int getUseDuration(@NotNull ItemStack stack, @NotNull LivingEntity entity) {
        return 50;
    }

    @Override
    public @NotNull ItemStack finishUsingItem(ItemStack stack, @NotNull Level level, @NotNull LivingEntity livingEntity) {
        if (livingEntity instanceof Player player) {
            player.addEffect(
                    new MobEffectInstance(
                            ModEffects.WATER_RECOVER, 200, 0, false, true
                    )
            );
            stack.hurtAndBreak(5, player, EquipmentSlot.MAINHAND);
            player.getCooldowns().addCooldown(this, 180);
        }
        return super.finishUsingItem(stack, level, livingEntity);
    }


    @Override
    public boolean hurtEnemy(@NotNull ItemStack stack, LivingEntity target, LivingEntity attacker) {
        if (attacker instanceof Player player)
            if (player.hasEffect(ModEffects.WATER_RECOVER) && player.getAttackStrengthScale(1) >= 0.85f) {
                player.level().getEntitiesOfClass(Player.class, AABB.ofSize(player.position(), 10, 4, 10))
                        .forEach(le -> le.heal((0.3f + 0.7f)));
            }
        return super.hurtEnemy(stack, target, attacker);
    }

    @Override
    public void postHurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
        stack.hurtAndBreak(1, attacker, EquipmentSlot.MAINHAND);
        super.postHurtEnemy(stack, target, attacker);
    }


    @Override
    public void onUseTick(Level level, LivingEntity entity, ItemStack stack, int remainingUseDuration) {
        var angle = entity.getViewVector(1).scale(4);
        angle = angle.add(entity.getDeltaMovement());
        if (level instanceof ServerLevel serverLevel) {
            serverLevel.sendParticles(
                    ParticleTypes.FALLING_WATER, entity.getX(), entity.getY(), entity.getZ(), 3, angle.x, angle.y, angle.z, 10
            );
        }
        for (int i = 0; i < 10; i++) {
            angle = entity.getViewVector(1).scale(0.5 * i + 1);
            level.addParticle(ParticleTypes.DRIPPING_WATER, entity.getX() + angle.x, entity.getY() + entity.getEyeHeight() + angle.y, entity.getZ() + angle.z, 0, 0, 0);
        }

        super.onUseTick(level, entity, stack, remainingUseDuration);
    }




    @Override
    public UseAnim getUseAnimation(ItemStack stack) {
        return UseAnim.BRUSH;
    }


}
